/*程序使用：VS2022 */
#include<stdio.h>
#include<easyx.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#pragma comment(lib,"Winmm.lib");
#define MAX_ANGLE 80		//钩子最大幅度
#define MANHATTAN_DIS(hook) sqrt((hook->x-hook->endx)*(hook->x-hook->endx)+(hook->y-hook->endy)*(hook->y-hook->endy));//钩子长度计算公式
#define MAXNUM 10
int flag = 0;
enum Dir { Left, Right };
enum HookState { Normal, Long, Short };
enum CoinType { Gold, Wallet, Stone, Max };
IMAGE img_bk;
IMAGE imgs[4];
void drawImg(int x, int y, IMAGE* src)
{
	// 变量初始化
	DWORD* pwin = GetImageBuffer();			//窗口缓冲区指针
	DWORD* psrc = GetImageBuffer(src);		//图片缓冲区指针
	int win_w = getwidth();				//窗口宽高
	int win_h = getheight();
	int src_w = src->getwidth();				//图片宽高
	int src_h = src->getheight();

	// 计算贴图的实际长宽
	int real_w = (x + src_w > win_w) ? win_w - x : src_w;			// 处理超出右边界
	int real_h = (y + src_h > win_h) ? win_h - y : src_h;			// 处理超出下边界
	if (x < 0) { psrc += -x;			real_w -= -x;	x = 0; }	// 处理超出左边界
	if (y < 0) { psrc += (src_w * -y);	real_h -= -y;	y = 0; }	// 处理超出上边界


	// 修正贴图起始位置
	pwin += (win_w * y + x);

	// 实现透明贴图
	for (int iy = 0; iy < real_h; iy++)
	{
		for (int ix = 0; ix < real_w; ix++)
		{
			byte a = (byte)(psrc[ix] >> 24);//计算透明通道的值[0,256) 0为完全透明 255为完全不透明
			if (a > 100)
			{
				pwin[ix] = psrc[ix];
			}
		}
		//换到下一行
		pwin += win_w;
		psrc += src_w;
	}
}

//这里声明函数来实现一些功能

struct Role {
	float x;
	float y;//角色位置
	int  width;
	int  height;//角色大小
	int money;//分数
};
struct Hook {
	float x;
	float y;//钩子起点位置
	float endx;
	float endy;//钩子伸长之后位置
	float lenth;//钩子长度
	float angle;//角度
	int state;
	int dir;
	int index;//钩子的起始状态
};
struct Object {
	int x;
	int y;//物品位置
	int width;
	int height;//物品模型大小
	int value;//物品得分
	bool isdie;//物品生成状态
	int type;
};
Role role;
Hook hook;
Object ob[MAXNUM];
void init();
void initResource();
void draw();
void initResource() {
	loadimage(&img_bk, "./res/bk.jpg", 0, getheight() - 120);
	for (int i = 0; i < 4; i++) {
		char str[40] = { 0 };
		sprintf(str, "./res/%d.png", i);
		loadimage(imgs + i, str);//导入图片素材
	}
}
void init_ob(Object* ob, int x, int y, int type) {
	ob->x = x;
	ob->y = y;//物品生成位置
	ob->type = type;
	ob->isdie = false;
	ob->height = imgs[ob->type].getheight();
	ob->width = imgs[ob->type].getwidth();

}
void ob_draw(Object* ob) {
	for (int i = 0; i < MAXNUM; i++) {
		if (!ob->isdie)
			drawImg(ob->x, ob->y, imgs + ob->type);//物品素材导入绘制
	}
}
void init_role(Role* role, int x, int y) /*矿工属性设置*/{
	role->x = x;
	role->y = y;//位置
	role->width = imgs[3].getwidth();
	role->height = imgs[3].getheight();//模型大小
	role->money = 0;//初始得分为0
}
void role_draw(Role* role) {
	drawImg((getwidth() - imgs[3].getwidth()) / 2, 0, imgs + 3);
	settextstyle(48, 0, "正楷");//字体
	settextcolor(RED);//颜色
	setbkmode(TRANSPARENT);
	char buf[256] = { 0 };
	sprintf(buf, "金币数：%d ", role->money);
	outtextxy(20, (role->height - textheight(buf)) / 2, buf);//分数显示
}
void init_hook(Hook* hook, int x, int y)/*钩子的初始化*/ {
	hook->x = x;
	hook->y = y;//钩子起始位置
	hook->lenth = 50;//固定钩子长度
	hook->endx = x;
	hook->endy = y + hook->lenth;
	hook->angle = 0;
	hook->state = Normal;//初始状态为正常
	hook->dir = Right;//初始方向为向右
	hook->index = -1;

}
void hook_draw(Hook* hook)/*绘制钩子*/ {
	//设置线条的样式：
	setlinestyle(PS_SOLID, 3);//风格
	setlinecolor(BLACK);//颜色
	line(hook->x, hook->y, hook->endx, hook->endy);
	setfillcolor(BROWN);
	solidcircle(hook->endx, hook->endy, 5);
}
void hook_swing/*让钩子动起来*/(Hook* hook, float speed) {
	if (hook->state == Normal)/*正常状态*/{
		if (hook->angle > MAX_ANGLE) /*转到极限回方向*/{
			hook->dir = Left;
		}
		else if (hook->angle < -MAX_ANGLE)  /*转到极限回方向*/{
			hook->dir = Right;
		}
		if (hook->dir == Left) {
			hook->angle -= speed;
		}
		else if (hook->dir == Right) {
			hook->angle += speed;
		}
		hook->endx = sin(3.1415 / 180 * hook->angle) * hook->lenth + hook->x;//x方向分速度
		hook->endy = cos(3.1415 / 180 * hook->angle) * hook->lenth + hook->y;//y方向分速度
	}
}
void control_hook(Hook* hook, float speed) /*游戏控制*/ {
	if (GetAsyncKeyState(VK_SPACE) & 0x8000 && hook->state == Normal) {
		hook->state = Long;
		flag = 1;//空格改变状态为伸长
	}
	if (GetAsyncKeyState(VK_SPACE) & 0x8000 && hook->state == Long && flag == 1 && hook->lenth > 280) {
		hook->state = Short;
		flag = 0;//空格继续改变状态为缩短
	}
	if (hook->state == Long)/*伸长中*/ {
		hook->lenth += speed;
		hook->endx = hook->x + sin(3.1415 / 180 * hook->angle) * hook->lenth;
		hook->endy = hook->y + cos(3.1415 / 180 * hook->angle) * hook->lenth;//分速度为正
		if (hook->endx<0 || hook->endx>getwidth() ||
			hook->endy > getheight()) {
			hook->state = Short;
		}
	}
	if (hook->state == Short) {
		hook->lenth -= speed;
		hook->endx = hook->x + sin(3.1415 / 180 * hook->angle) * hook->lenth;//分速度为负
		hook->endy = hook->y + cos(3.1415 / 180 * hook->angle) * hook->lenth;
		if (hook->lenth < 50) {
			hook->state = Normal;//改变状态为正常
		}
	}
}
void HookGet(Object* ob) /*钩子抓取判定*/ {
	if (hook.state == Normal && hook.index != -1) {
		ob[hook.index].isdie = true;
		role.money += rand() % 100;
		hook.index = -1;
	}
	if (hook.state == Normal) {
		return;
	}
	for (int i = 0; i < MAXNUM; i++) {
		//printf("haha!\n");
		if (!(ob + i)->isdie && hook.endx > (ob + i)->x && hook.endx<(ob + i)->x + (ob + i)->width &&
			hook.endy>(ob + i)->y && hook.endy < (ob + i)->y + (ob + i)->height) /*触碰到物品实体体积*/{
			hook.index = i;
			break;
		}//就抓到了
	}
	if (hook.index != -1) {
		hook.state = Short;
		(ob + hook.index)->x = hook.endx - (ob + hook.index)->width / 2;
		(ob + hook.index)->y = hook.endy - (ob + hook.index)->height / 2;

	}

}
void draw() /*整体绘制*/ {

	putimage(0, 120, &img_bk);
	setfillcolor(YELLOW);
	solidrectangle(0, 0, getwidth(), imgs[3].getheight());
	role_draw(&role);
	hook_draw(&hook);
	for (int i = 0; i < MAXNUM; i++) {
		if (!ob[i].isdie)
			ob_draw(&ob[i]);
	}
}
void init() /*游戏运行*/ {
	mciSendString("./res/open aa.mp3 ", 0, 0, 0);//打开音乐
	mciSendString("play ./res/aa.mp3 repeat", 0, 0, 0);//播放音乐
	initResource();
	init_role(&role, (getwidth() - imgs[3].getwidth()) / 2, 0);
	init_hook(&hook, role.x + 40, role.y + 95);
	for (int i = 0; i < MAXNUM; i++) {
		int x = rand() % (getwidth() - 40) + 20;
		int y = rand() % (getheight() - role.height) + role.height;
		init_ob(&ob[i], x, y, rand() % Max);
	}
}
int main() /*主题函数*/ {
	initgraph(1080, 640, EW_SHOWCONSOLE);//创建窗口
	srand(time(0));//时间随机
	init();//开始运行

	while (1)/*防止闪退*/ {
		BeginBatchDraw();
		draw();
		EndBatchDraw();
		hook_swing(&hook, 0.3);
		control_hook(&hook, 3);
		HookGet(ob);
	}
	return 0;
}